<template>
  <div class="qts-marking">
    <TopicList :qtsIndexData="props.qtsIndexData"></TopicList>
    <main @click.self="onClickMain">
      <section class="qbm-header">
        <div class="block-num flex-1">
          <TopicDetail ref="topicDetailDom"></TopicDetail>
        </div>

        <div class="block-num flex-1" v-if="singleQtsCorrectStore.isRemark">
          <span>
            {{ singleQtsCorrectStore.currentQtsData.order_text }}题块
          </span>
          <template v-if="remarkData.remarkCorrected">
            <span class="remark-list-info">
              {{
                `回评（${remarkData.remarkOrder}/${currentAnswerData.length}）`
              }}
            </span>
            <span class="correct-score">已评{{ scoreText }}</span>
          </template>
        </div>

        <button
          :disabled="!singleQtsCorrectStore.isRemark"
          @click="toUnmarkedQuestionBlock()"
          class="qbm-header__button btn-continue"
        >
          继续阅卷
        </button>
        <button
          :disabled="!hasPreviousBlock"
          @click="toPreviousQuestionBlock()"
          class="qbm-header__button btn-previous"
        >
          回评上一份
        </button>
        <button
          :disabled="!hasNextBlock"
          @click="toNextQuestionBlock()"
          class="qbm-header__button btn-next"
        >
          回评下一份
        </button>
        <span class="qbm-header__divider"></span>
        <button
          :disabled="
            noTopic ||
            scaleRatio === 1 ||
            currentAnswerData[currentIndex]?.response_url == ''
          "
          @click="resetScale()"
          class="qbm-header__button btn-reset-scale"
        ></button>

        <button
          :disabled="
            noTopic ||
            reachZoomInLimit ||
            currentAnswerData[currentIndex]?.response_url == ''
          "
          @click="zoomIn()"
          class="qbm-header__button btn-zoom-in"
        ></button>
        <button
          :disabled="
            noTopic ||
            reachZoomOutLimit ||
            currentAnswerData[currentIndex]?.response_url == ''
          "
          @click="zoomOut()"
          class="qbm-header__button btn-zoom-out"
        ></button>
        <button
          :disabled="
            noTopic || currentAnswerData[currentIndex]?.response_url == ''
          "
          @click="rotate()"
          class="qbm-header__button btn-rotate"
        ></button>
      </section>

      <article class="qbm-main" @click="onClickMain">
        <div
          v-if="
            !singleQtsCorrectStore.isRemark &&
            singleQtsCorrectStore.currentQtsData &&
            singleQtsCorrectStore.currentQtsData.await_grade == 0
          "
          class="empty-paper-tips"
        >
          <img
            src="@/assets/images/single-correct/done.png"
            :draggable="false"
          />
          <p>当前题块已批改完毕，感谢老师的辛勤付出！</p>
        </div>
        <transition v-else :name="slideAnimeName">
          <div v-if="currentAnswerData[currentIndex]" v-show="showsBlockImg">
            <ScoreClick
              :total-score="currentAnswerData[currentIndex]?.set_score_total"
              v-if="currentAnswerData[currentIndex]?.response_url !== '[]'"
            >
              <QtsBlockImg
                :imgUrl="currentAnswerData[currentIndex]?.response_url"
                :scaleRatio="scaleRatio"
                :isRotated="isRotated"
              ></QtsBlockImg>
            </ScoreClick>
            <div
              v-if="
                (currentAnswerData[currentIndex]?.response_url == '[]' ||
                  currentAnswerData[currentIndex]?.response_url == '') &&
                currentAnswerData[currentIndex]?.response
              "
              class="answer_text"
            >
              <ScoreClick
                :total-score="currentAnswerData[currentIndex]?.set_score_total"
              >
                <div
                  v-if="currentAnswerData[currentIndex]?.response != '[]'"
                  v-html="
                    getNormalizeData(
                      JSON.parse(currentAnswerData[currentIndex]?.response),
                      getParseData(
                        singleQtsCorrectStore.currentQtsData.question_detail
                      )
                    )
                  "
                ></div>
                <NoData v-else></NoData>
              </ScoreClick>
            </div>
            <!-- 批注模块 -->
            <div class="annotation-box" v-if="maskType === 'text'">
              <div
                class="text-box"
                v-if="!isAddingAnnotation && annotation_text"
              >
                文本批注：{{ annotation_text }}
              </div>
              <AnnotationText
                v-if="isAddingAnnotation"
                @cancel="onToggleMark"
                @update="onUpdateText"
                :value="annotation_text"
              />
              <div class="flex-end" v-else>
                <el-button
                  type="primary"
                  text
                  class="annotation-btn flex"
                  @click="onToggleMark"
                >
                  <AnnotationBtn class="img" />
                  批注
                </el-button>
              </div>
            </div>
          </div>
        </transition>
      </article>

      <transition name="fade">
        <div v-show="showsSubmitHint" class="submit-hint">
          {{ submittedStatus }}
        </div>
      </transition>
    </main>

    <ScoreBoard
      :answerInfo="currentAnswerData[currentIndex] || {}"
      :await-grade="singleQtsCorrectStore.currentQtsData.await_grade"
      :total-score="currentAnswerData[currentIndex]?.set_score_total || 0"
      :title="singleQtsCorrectStore.currentQtsData.order_text"
      :correctType="currentAnswerData[currentIndex]?.set_score_total ? 2 : 1"
      @submitScore="changeScore"
      @correctSuccess="correctSuccess"
    ></ScoreBoard>
  </div>
</template>

<script setup>
import { ref, reactive, computed, onBeforeUnmount } from 'vue'
import $bus from '@/utils/tools/bus'
import { getNormalizeData, getParseData } from '@/utils/answer'
import TopicDetail from '@/views/single-correct/components/TopicDetail.vue'
import ScoreBoard from '@/components/score-board/ScoreBoard.vue'
import ScoreClick from '@/components/score-board/ScoreClick.vue'
import TopicList from '@/views/single-correct/components/TopicList.vue'
import QtsBlockImg from '@/views/single-correct/components/QtsBlockImg.vue'
import NoData from '@/components/homework-systom/NoData.vue'
import { getStudentMsg } from '@/apis/single-correct/index'
import { useSingleQtsCorrectStore } from '@/stores/single-correct'
import AnnotationBtn from '@/assets/images/assignment/annotation.svg'
import AnnotationText from '@/components/annotation/AnnotationText.vue'
import { storeToRefs } from 'pinia'

const singleQtsCorrectStore = useSingleQtsCorrectStore()
const { annotation_text } = storeToRefs(useSingleQtsCorrectStore())

const emit = defineEmits(['getCurrentStuInfo'])
const props = defineProps({
  qtsIndexData: { type: Array, required: true }
})

// #批注相关
const isAddingAnnotation = ref(false) // 是否开启批注

const onToggleMark = () => {
  isAddingAnnotation.value = !isAddingAnnotation.value
  if (!isAddingAnnotation.value) resetAnno()
}
const resetAnno = () => {
  annotation_text.value = ''
}
const onUpdateText = value => {
  annotation_text.value = value
  isAddingAnnotation.value = false
}
const maskType = computed(() => {
  let urlString = currentAnswerData.value[currentIndex.value]?.response_url
  return JSON.parse(urlString || '[]').length ? 'pic' : 'text'
})

const changeScore = (score, list) => {
  console.log(score, list)
}

// #region -------header-------
const scaleRatio = ref(1)
const isRotated = ref(false)
const hasPreviousBlock = computed(() => {
  return (
    (singleQtsCorrectStore.isRemark && remarkData.remarkOrder != 1) ||
    (singleQtsCorrectStore.currentQtsData.await_grade != 0 &&
      singleQtsCorrectStore.currentQtsData.grade_rate != 0 &&
      !singleQtsCorrectStore.isRemark)
  )
})

const hasNextBlock = computed(() => {
  return (
    singleQtsCorrectStore.isRemark &&
    remarkData.remarkStudentId != remarkData.lastStuRecordId &&
    remarkData.remarkCorrected &&
    remarkData.remarkOrder != currentAnswerData.value.length
  )
})

const noTopic = computed(() => {
  return singleQtsCorrectStore.isRemark
    ? false
    : singleQtsCorrectStore.currentQtsData.await_grade == 0
})

const reachZoomInLimit = computed(() => {
  return Math.round(scaleRatio.value) === 3
})

const reachZoomOutLimit = computed(() => {
  return Math.round(scaleRatio.value * 10) === 4
})

const scoreText = computed(() => {
  let score = currentAnswerData.value[currentIndex.value]?.score
  return score == 2 ? '对' : score == 1 ? '半对' : '错'
})

const toUnmarkedQuestionBlock = async () => {
  correctStatus.value = -1
  showSlideAni(true)
  singleQtsCorrectStore.isRemark = false
  await getQtsDetail()
  emit('getCurrentStuInfo', currentAnswerData.value[currentIndex.value])
}

const toPreviousQuestionBlock = async () => {
  showSlideAni(true)
  if (singleQtsCorrectStore.isRemark) {
    currentIndex.value++
    remarkData.remarkOrder--
    remarkData.remarkStudentId =
      currentAnswerData.value[currentIndex.value].student_id
    remarkData.remarkCorrected =
      currentAnswerData.value[currentIndex.value].teacher_correct != -1
  } else {
    correctStatus.value == -1
    singleQtsCorrectStore.isRemark = true
    await getQtsDetail()
    currentIndex.value = 0
    remarkData.remarkCorrected = true
    remarkData.remarkOrder = currentAnswerData.value.length
    remarkData.remarkStudentId = currentAnswerData.value[0].student_id
    // remarkData.lastStuRecordId = currentAnswerData.value[0].student_id
  }
  emit('getCurrentStuInfo', currentAnswerData.value[currentIndex.value])
}

const toNextQuestionBlock = () => {
  showSlideAni(false)
  remarkData.remarkOrder++
  currentIndex.value--
  remarkData.remarkStudentId =
    currentAnswerData.value[currentIndex.value]?.student_id
  remarkData.remarkCorrected =
    currentAnswerData.value[currentIndex.value]?.teacher_correct != -1
  correctFinish.value = currentIndex.value == -1 //批改完成
  emit('getCurrentStuInfo', currentAnswerData.value[currentIndex.value])
}

const correctSuccess = data => {
  if (!singleQtsCorrectStore.isRemark) {
    toNextQuestionBlock()
  } else {
    if (currentIndex.value != 0) {
      toNextQuestionBlock()
    } else {
      //回评完全部已批改的，切换到继续阅卷
      toUnmarkedQuestionBlock()
    }
  }
  submittedStatus.value =
    data.status == MarkingStatus.right
      ? '对'
      : data.status == MarkingStatus.wrong
        ? '错'
        : '半对'
  showSubmitAni()
}

const resetScale = () => {
  scaleRatio.value = 1
}
const zoomIn = () => {
  scaleRatio.value += 0.2
}
const zoomOut = () => {
  scaleRatio.value -= 0.2
}
const rotate = () => {
  isRotated.value = !isRotated.value
}
// #endregion

// #region -------main-------
const MarkingStatus = {
  right: 2, //正确
  half: 1, //半对
  wrong: 0 //错误
}
const slideAnimeName = ref('slide-next')
const showsBlockImg = ref(true)
const showsSubmitHint = ref(false)
const topicDetailDom = ref()
const currentIndex = ref(0) //当前批改学生下标
const currentAnswerData = ref([]) //当前批改学生大题信息列表
const correctFinish = ref(false) //是否批改完成
const submittedStatus = ref()
const correctStatus = ref(-1) //-1 未选择是否批改或已批改
const remarkData = reactive({
  remarkOrder: 0, //回评编号(与currentIndex排序相反)
  remarkStudentId: '', //选中回评的学生id
  remarkCorrected: false, //回评中选中的题目是否已批改
  lastStuRecordId: '' //批改记录中编号最后一个(即列表第一个)学生id
})

$bus.on('change-correct-status', data => {
  correctStatus.value = data
})

$bus.on('on-select-qts', async () => {
  await getQtsDetail()
  currentIndex.value = currentAnswerData.value.length - 1
  //设置correctFinish
  remarkData.remarkOrder = 0
  remarkData.remarkStudentId = ''
  remarkData.remarkCorrected = false
  remarkData.lastStuRecordId = ''
  emit('getCurrentStuInfo', currentAnswerData.value[currentIndex.value])
})

//获取作业题目的学生答题信息
const getQtsDetail = async () => {
  let res = await getStudentMsg({
    task_id: singleQtsCorrectStore.taskId,
    class_id: singleQtsCorrectStore.classId,
    class_type: singleQtsCorrectStore.classType,
    question_id: singleQtsCorrectStore.currentQtsData.question_id,
    item_type: singleQtsCorrectStore.currentQtsData.item_type
  })
  if (res.code == 1 && res.data) {
    currentIndex.value = 0
    currentAnswerData.value = res.data.filter(v => {
      const isSubmitted = v.submit == 1
      const isRemarkMode = singleQtsCorrectStore.isRemark
      const teacherCorrected = v.teacher_correct != -1

      if (isRemarkMode) {
        if (correctStatus.value === 1 || correctStatus.value === -1) {
          return isSubmitted && teacherCorrected
        } else if (correctStatus.value === 2) {
          return isSubmitted && !teacherCorrected
        } else {
          return isSubmitted
        }
      } else {
        return isSubmitted && !teacherCorrected
      }
    })
  }
}

const onClickMain = () => {
  topicDetailDom.value?.hiddenDetail()
}

//批改记录选择学生题目
$bus.on('select-remark-stu-qts', async data => {
  showSlideAni(false)
  singleQtsCorrectStore.isRemark = true
  remarkData.remarkOrder = data.order
  remarkData.remarkStudentId = data.studentId
  remarkData.remarkCorrected = data.correctStatus != -1
  remarkData.lastStuRecordId = data.lastStuRecordId

  await getQtsDetail()
  currentIndex.value = currentAnswerData.value.findIndex(
    stuAns => stuAns.student_id == data.studentId
  )
  emit('getCurrentStuInfo', currentAnswerData.value[currentIndex.value])
})

const showSlideAni = isPer => {
  slideAnimeName.value = isPer ? 'slide-previous' : 'slide-next'
  showsBlockImg.value = false
  let timer = setTimeout(() => {
    showsBlockImg.value = true
    clearTimeout(timer)
  }, 200)
}

const showSubmitAni = () => {
  showsSubmitHint.value = true
  let timer = setTimeout(() => {
    showsSubmitHint.value = false
    clearTimeout(timer)
  }, 500)
}
// #endregion

onBeforeUnmount(() => {
  $bus.off('select-remark-stu-qts')
  $bus.off('change-correct-status')
})
</script>

<style lang="less" scoped>
@baseURL: '@/assets/images/single-correct';
.slide-previous-leave-active,
.slide-previous-enter-active,
.slide-next-leave-active,
.slide-next-enter-active {
  transition: all 150ms;
}
.slide-previous-leave-to {
  transform: translateX(100%);
}
.slide-previous-enter {
  opacity: 0;
}
.slide-next-leave-to {
  transform: translateX(-100%);
}
.slide-next-enter {
  opacity: 0;
}

.fade-enter-active,
.fade-leave-active {
  transition: opacity 300ms;
}
.fade-enter,
.fade-leave-to {
  opacity: 0;
}

.qts-marking {
  background-color: #fcfbfb;
  display: flex;
  height: calc(100vh - 80px);

  main {
    position: relative;
    margin-left: 56px;
    width: calc(100% - 464px);
    min-height: 220px;
    display: flex;
    flex-direction: column;
    .qbm-header {
      flex: 0 0 auto;
      box-sizing: border-box;
      min-height: 66px;
      display: flex;
      justify-content: flex-end;
      align-items: center;
      flex-wrap: wrap;
      .block-num {
        display: flex;
        align-items: center;
      }
      .remark-list-info {
        padding-left: 20px;
        font-size: 20px;
        font-weight: bold;
      }
      .flex-1 {
        flex: 1 0 auto;
      }
      .correct-score {
        margin: 2px;
        padding: 0 14px;
        height: 38px;
        border-radius: 19px;
        background-color: rgba(108, 208, 167, 0.3);
        line-height: 36px;
        text-align: center;
        font-size: 20px;
        font-weight: 700;
        color: #27ae61;
      }
      .qbm-header__button {
        flex: 0 0 auto;
        margin-left: 33px;
        border: 0;
        padding: 1px 0 0;
        outline: 0;
        background-color: transparent;
        background-repeat: no-repeat;
        background-position: left;
        line-height: 32px;
        font-size: 16px;
        font-weight: bold;
        color: #595959;
        cursor: pointer;

        &:disabled {
          color: #8c8c8c;
          opacity: 0.3;
          cursor: not-allowed;
        }

        @media screen and (max-width: 1470px) {
          margin-left: 20px;
        }
      }
      .btn-continue {
        padding-left: 37px;
        background-size: 28px 28px;
        background-image: url('@{baseURL}/btn-continue.png');
      }

      .btn-previous {
        padding-left: 18px;
        background-image: url('@{baseURL}/btn-previous.png');
      }

      .btn-next {
        padding: 1px 18px 0 0;
        background-image: url('@{baseURL}/btn-next.png');
        background-position: right;
      }

      .btn-reset-scale {
        padding: 0;
        width: 34px;
        height: 26px;
        background-image: url('@{baseURL}/btn-reset-scale.png');
        background-size: contain;
        cursor: pointer;

        &:disabled {
          background-image: url('@{baseURL}/btn-reset-scale-disabled.png');
          cursor: not-allowed;
        }
      }

      .btn-zoom-in {
        padding: 0;
        width: 25px;
        height: 29px;
        background-image: url('@{baseURL}/btn-zoom-in.png');
        background-size: contain;
        cursor: pointer;

        &:disabled {
          background-image: url('@{baseURL}/btn-zoom-in-disabled.png');
          cursor: not-allowed;
        }
      }

      .btn-zoom-out {
        padding: 0;
        width: 25px;
        height: 29px;
        background-image: url('@{baseURL}/btn-zoom-out.png');
        background-size: contain;
        cursor: pointer;

        &:disabled {
          background-image: url('@{baseURL}/btn-zoom-out-disabled.png');
          cursor: not-allowed;
        }
      }

      .btn-rotate {
        padding: 0;
        width: 31px;
        height: 31px;
        background-image: url('@{baseURL}/btn-rotate.png');
        background-size: contain;
        cursor: pointer;

        &:disabled {
          background-image: url('@{baseURL}/btn-rotate-disabled.png');
          cursor: not-allowed;
        }
      }
    }
    .qbm-main {
      flex: 1 1 auto;
      overflow: hidden;

      .empty-paper-tips {
        height: 80%;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;

        p {
          margin-top: 20px;
          font-size: 20px;
          font-weight: bold;
        }
        .continue-tip {
          font-size: 16px;
          color: #c9c9c9;
          font-weight: normal;
          color: #5f6b7c99;
          .continue-btn {
            text-decoration: underline;
            cursor: pointer;
          }
        }
        button {
          margin-top: 20px;
          width: 120px;
          height: 40px;
          color: #fff;
          background-color: #009cff;
          border: none;
          border-radius: 4px;
        }
      }

      .answer_text {
        padding: 40px;
        background-color: #fff;
        :deep(.text) {
          font-size: @size-big;
        }
      }
    }
  }

  aside {
    flex-shrink: 0;
    margin: 16px 35px 0;
    height: 806px;
    border: 1px solid #d9d9d9;
    box-sizing: border-box;
    width: 338px;
    border-radius: 3px;
    background-color: #ffffff;
    display: flex;
    flex-direction: column;
    overflow: auto;
    &::-webkit-scrollbar {
      width: 0;
    }
  }
}
.submit-hint {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  margin: auto;
  box-sizing: border-box;
  border: 8px solid #e84c3d;
  width: 197px;
  height: 197px;
  box-shadow: 0px 0px 43px rgba(0, 0, 0, 0.2);
  border-radius: 50%;
  background-color: #ffffff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 66px;
  color: #e84c3d;
}

.annotation-box {
  margin-top: 10px;
  .text-box {
    margin-top: 20px;
    padding: 10px;
    background-color: #fff;
  }
  .annotation-btn {
    .img {
      margin: -2px 4px 0 0;
    }
  }
}
</style>
